package de.homeR.android;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.StatusLine;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import android.app.ListActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.sax.Element;
import android.sax.EndElementListener;
import android.sax.EndTextElementListener;
import android.sax.RootElement;
import android.sax.StartElementListener;
import android.util.Log;
import android.util.Xml;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import de.homeR.android.pluginmanagement.ManageActivePluginsActivity;
import de.homeR.android.preferences.PreferencesActivity;

/**
 * @author André Stannek
 * 
 */
public class HomeRActivity extends ListActivity {

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	public final void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		try {
			@SuppressWarnings("synthetic-access")
			ArrayAdapter<PluginSelectListItemModel> adapter = new PluginSelectListAdapter(
					this, (new RetrieveXMLTask()).execute().get());
			setListAdapter(adapter);
		} catch (InterruptedException e) {
			Log.wtf(getClass().getSimpleName(), e);
		} catch (ExecutionException e) {
			Log.wtf(getClass().getSimpleName(), e);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu)
	 */
	@Override
	public final boolean onCreateOptionsMenu(final Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.mainmenu, menu);
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
	 */
	@Override
	public final boolean onOptionsItemSelected(final MenuItem item) {
		switch (item.getItemId()) {
		case R.id.preferences:
			startActivity(new Intent(HomeRActivity.this,
					PreferencesActivity.class));
			break;
		case R.id.addAdapter:
			startActivity(new Intent(HomeRActivity.this,
					ManageActivePluginsActivity.class));
			break;
		default:
			return false;
		}
		return true;
	}

	/**
	 * @author André Stannek
	 * 
	 */
	private static class RetrieveXMLTask extends
			AsyncTask<String, Void, List<PluginSelectListItemModel>> {

		/**
		 * 
		 */
		private static PluginSelectListItemModel currentModel;

		/*
		 * (non-Javadoc)
		 * 
		 * @see android.os.AsyncTask#doInBackground(Params[])
		 */
		@Override
		protected List<PluginSelectListItemModel> doInBackground(
				final String... params) {

			// GET
			StringBuilder builder = new StringBuilder();
			HttpClient client = new DefaultHttpClient();
			HttpGet httpGet = new HttpGet(
					"http://10.0.2.2:8080/homer/rest/config/configuredplugins");
			try {
				HttpResponse response = client.execute(httpGet);
				StatusLine statusLine = response.getStatusLine();
				int statusCode = statusLine.getStatusCode();
				if (statusCode == 200) {
					HttpEntity entity = response.getEntity();
					BufferedReader reader = new BufferedReader(
							new InputStreamReader(entity.getContent()));
					String line;
					while ((line = reader.readLine()) != null) {
						builder.append(line);
					}
					return parsePluginList(builder.toString());
				}
				Log.e(CONNECTIVITY_SERVICE, statusLine.toString());
			} catch (ClientProtocolException e) {
				Log.e(CONNECTIVITY_SERVICE, "", e);
			} catch (IOException e) {
				Log.e(CONNECTIVITY_SERVICE, "", e);
			} catch (SAXException e) {
				Log.e(getClass().getSimpleName(),
						"Webservice result contained unkonwn structure", e);
			} catch (ParserConfigurationException e) {
				Log.wtf(getClass().getSimpleName(), e);
			}

			return new ArrayList<PluginSelectListItemModel>();
		}

		/**
		 * @param xml
		 *            the xml string
		 * @return a list of all {@link PluginSelectListItemModel} created from
		 *         the xml input.
		 * @throws ParserConfigurationException
		 *             if parser is falsely configured
		 * @throws IOException
		 *             shouldn't happen
		 * @throws SAXException
		 *             if XML had the wrong structure
		 */
		private static List<PluginSelectListItemModel> parsePluginList(
				final String xml) throws SAXException, IOException,
				ParserConfigurationException {

			final List<PluginSelectListItemModel> result = new ArrayList<PluginSelectListItemModel>();
			RootElement root = new RootElement(
					"pluginMetaInformationCollection");
			Element plugin = root.getChild("plugin");
			// Element jarPath = plugin.getChild("jarPath");
			Element name = plugin.getChild("name");
			// Element pluginClassName = plugin.getChild("pluginClassName");

			plugin.setStartElementListener(new StartElementListener() {
				@SuppressWarnings("synthetic-access")
				public void start(final Attributes attributes) {
					currentModel = new PluginSelectListItemModel();
				}
			});

			name.setEndTextElementListener(new EndTextElementListener() {
				@SuppressWarnings("synthetic-access")
				public void end(final String body) {
					currentModel.setName(body);
				}
			});

			plugin.setEndElementListener(new EndElementListener() {
				@SuppressWarnings("synthetic-access")
				public void end() {
					result.add(currentModel);
				}
			});

			Xml.parse(xml, root.getContentHandler());
			return result;
		}

	}
}
